//
//  UIDoomScreenView.m
//  MobileDoom
//
//  Created by Steven Troughton-Smith on 30/05/2008.
//  Copyright 2008 Glenstal. All rights reserved.
//


#import "iPhoneOSBuild.h"


#if USE_UIKIT

#import "UIDoomScreenView.h"
#import "z_zone.h"

#if USE_COREANIMATION
#import <QuartzCore/QuartzCore.h>
#endif


static UIDoomScreenView *sharedInstance = nil;

unsigned int size;
unsigned long *screen;

unsigned long hightable[256], lowtable[256];
void gentables()
{
	for (int i = 0; i < 256; i++)
	{
		// low byte
		unsigned long red = (unsigned long)((i & 31) * 255.f / 31.f);
		unsigned long lowgreen = (unsigned long)(((i >> 5) & 7) * 255.f / 63.f);
		lowtable[i] = red | (lowgreen << 8);
		// high byte
		unsigned long highgreen = (unsigned long)(((i & 7) << 3) * 255.f / 63.f);
		unsigned long blue = (unsigned long)((i >> 3) * 255.f / 31.f);
		hightable[i] = (blue << 16) | (highgreen << 8);
	}
}
inline unsigned convert_rgb565_to_rgb888(unsigned short rgb565)
{
	return hightable[rgb565 >> 8] + lowtable[rgb565 & 255];
}

void setFB(unsigned long *fbuffer)
{	
	int x, y, i = 0;
		
	for (y=0; y < doom_resolution_height; y++)
	{
		for (x=0; x< doom_resolution_width; x++)
		{
			screen[doom_resolution_width*y+x] = convert_rgb565_to_rgb888(fbuffer[doom_resolution_width*y+x]); 
		}		
	}
}

void updateScreen() {
	[sharedInstance performSelectorOnMainThread:@selector(updateScreen) withObject:nil waitUntilDone: NO];
}

int getNextEvent(event_t *event) {
	return [sharedInstance getNextEvent:event];
}

@implementation UIDoomScreenView

- (void)updateScreen {
	[sharedInstance setNeedsDisplay];
}

- (id)initWithCoder:(NSCoder*)coder {
	if ((self = [super initWithCoder:coder]))
	{		
		gentables();

		sharedInstance = self;

		NSLog(@"UIDoomScreenView initWithCoder:");
		size = doom_resolution_width*doom_resolution_height;
		
		mutex = [[NSLock alloc] init];
		
		colors = CGColorSpaceCreateDeviceRGB();
		colorSpace = CGColorSpaceCreateIndexed(colors, 255, doomPaletteTable);	
		
		CGColorSpaceRetain(colors);
	
		int delta = 4;
		
		screen   = (unsigned char*)malloc(delta *size);
		provider = CGDataProviderCreateWithData(NULL, screen,  delta *size, NULL);	
	
		unsigned char *c;		 
		c = screen; 
		int i;		 
		for (i=0; i<(delta*doom_resolution_width*doom_resolution_height); i++) {		 
			*c++ = 0;		 
		}	
						
	}
	return self;
}	

	
- (void)drawRect:(CGRect)rect {
	
	screenImage = CGImageCreate(	
								doom_resolution_width,
								doom_resolution_height,
								8, // bpc
								32, // bpp
								4 * doom_resolution_width, // bpr
								colors,
								kCGBitmapByteOrder32Host| kCGImageAlphaNoneSkipFirst,
								provider,
								NULL,
								NO,
								kCGRenderingIntentDefault
								);
	
#if USE_COREGRAPHICS
	CGContextRef ctx = UIGraphicsGetCurrentContext();
	CGContextScaleCTM(ctx, 1.0, -1.0);
	CGContextDrawImage(ctx, CGRectMake(0, -doom_resolution_height,doom_resolution_width,doom_resolution_height), screenImage);
//	CGContextDrawImage(ctx, CGRectMake(0, -480, 640, 480), screenImage);
	CGImageRelease (screenImage);
#endif
	
#if USE_COREANIMATION
	screenLayer = [[CALayer layer] retain];
	[screenLayer setFrame: self.bounds];
	
	[screenLayer setContents: screenImage];
	[screenLayer setOpaque: YES];
	[[self layer] addSublayer: screenLayer];
#endif
}

- (void)dealloc {
	[super dealloc];
}

@end

#endif
